import { message } from 'ant-design-vue'
import axios, { type AxiosRequestConfig } from 'axios'
import { showMessage } from './status'

import router from '@/router'

// 创建 axios 实例
const service = axios.create({
  baseURL: import.meta.env.VITE_APP_BASE_API || '/dev-api',
  timeout: 10000,
})

// 全局请求取消控制器
const pendingRequests = new Map<string, AbortController>()

// 生成请求的唯一标识
const generateRequestKey = (config: AxiosRequestConfig): string => {
  const { method, url, params, data } = config
  return `${method}-${url}-${JSON.stringify(params || null)}-${JSON.stringify(data || null)}`
}

// 请求拦截器（添加 token 等）
service.interceptors.request.use(
  (config) => {
    const token = localStorage.getItem('accessToken')
    if (token) config.headers.Authorization = token

    // 取消重复请求
    const requestKey = generateRequestKey(config)
    if (pendingRequests.has(requestKey)) {
      pendingRequests.get(requestKey)?.abort()
    }

    // 创建新的AbortController
    const controller = new AbortController()
    config.signal = controller.signal
    pendingRequests.set(requestKey, controller)

    return config
  },
  (error) => {
    // 对请求错误做些什么
    return Promise.reject(error)
  }
)

// 响应拦截器（统一处理错误）
service.interceptors.response.use(
  (response) => {
    // 请求完成后移除pending状态
    const requestKey = generateRequestKey(response.config)
    pendingRequests.delete(requestKey)
    return response.data
  },
  (error) => {
    console.log(error)

    // 对响应错误做些什么
    if (error.response) {
      if (error.response.data?.message) {
        message.error(error.response.data?.message)
      } else {
        message.error(showMessage(error.response.status))
      }
      if (error.response.status === 401) {
        // 1. 清除所有pending请求
        pendingRequests.forEach((controller) => controller.abort())
        pendingRequests.clear()

        // 2. 清除用户凭证
        localStorage.removeItem('accessToken')

        // 3. 重定向到登录页
        router.replace({
          path: '/login',
          query: { redirect: router.currentRoute.value.fullPath },
        })

        // 4. 提示错误信息
        message.error('登录已过期，请重新登录')
      }
    } else if (error.request) {
      message.error('请求失败，请检查网络连接')
    } else {
      message.error('请求配置错误')
    }
    return Promise.reject(error)
  }
)

export default service

/**
 * 1. 请求取消机制：

使用 AbortController 实现请求取消
通过 Map 存储所有 pending 状态的请求控制器
每个请求生成唯一标识（method + url）
 */
